package com.yunhe.device.service.device.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.google.common.collect.Lists;
import com.yunhe.common.excel.ExcelExport;
import com.yunhe.common.excel.PoiUtils;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.filter.ServerContextHolder;
import com.yunhe.common.model.PageParam;
import com.yunhe.common.model.ResultObject;
import com.yunhe.common.model.authority.RealStation;
import com.yunhe.common.model.office.Office;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.common.util.StringUtil;
import com.yunhe.device.client.AuthorityClient;
import com.yunhe.device.domain.base.DeviceType;
import com.yunhe.device.domain.base.EquipmentAttributes;
import com.yunhe.device.domain.base.PointDataType;
import com.yunhe.device.domain.device.EquipStatusCountVo;
import com.yunhe.device.domain.device.EquipTypeCountVo;
import com.yunhe.device.domain.device.Device;
import com.yunhe.device.model.device.*;
import com.yunhe.device.repository.authority.ResourceTreeRepository;
import com.yunhe.device.repository.authority.impl.AuthorityDao;
import com.yunhe.device.repository.base.AnalogTypeRepository;
import com.yunhe.device.repository.base.EquipmentAttributesRepository;
import com.yunhe.device.repository.base.EquipmentTypeRepository;
import com.yunhe.device.repository.device.EquipmentRepository;
import com.yunhe.device.repository.device.impl.EquipmentDao;
import com.yunhe.device.service.device.EquipmentService;
import com.yunhe.device.utils.UploadUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yunhe.common.util.CollectionUtil;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @ClassName EquipmentServiceImpl
 * @Description TODO
 * @Author HeTao
 * @Date 2021/7/15 17:43
 * @Version 1.0
 **/
@Service
@Slf4j
public class EquipmentServiceImpl implements EquipmentService {

    @Autowired
    private EquipmentRepository equipmentRepository;

    @Autowired
    private EquipmentDao equipmentDao;

    @Autowired
    private AuthorityClient authorityClient;

    @Autowired
    private EquipmentTypeRepository equipmentTypeRepository;

    @Autowired
    private AnalogTypeRepository analogTypeRepository;

    @Autowired
    private EquipmentAttributesRepository equipmentAttributesRepository;

    @Autowired
    private ResourceTreeRepository resourceTreeRepository;

    @Autowired
    private AuthorityDao authorityDao;

    private static LinkedBlockingQueue<EquipmentBo> deviceQueue = new LinkedBlockingQueue<>();


    
    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public Device createEquipmente(EquipmentBo equipmentBo) throws UniqueConstraintsException, PinyinException {
        Device equipment = new Device();
        equipmentBo.setId(null);
        processBeforeSave(equipmentBo);
        BeanUtils.copyProperties(equipmentBo,equipment);
        String format = DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date());
        equipment.setSn(DateTimeUtils.getTimestamp(format,null));
        equipment.setCreateTime(format);
        List<EquipAttrValueVo> equipAttrValueVos = equipmentBo.getEquipAttrValueVos();
        List<EquipAttrValueVo> initEquipAttrValueVos = new ArrayList<>();
        List<EquipAttrValueVo> customizeEquipAttrValueVos = new ArrayList<>();
        if(!CollectionUtil.isEmpty(equipAttrValueVos)){
            //过滤出用户自定义属性
            customizeEquipAttrValueVos = equipAttrValueVos.stream().filter(equipAttrValueVo -> {
                return "02".equals(equipAttrValueVo.getType());
            }).collect(Collectors.toList());
            if(!CollectionUtil.isEmpty(customizeEquipAttrValueVos)){
                String jsonString = JSONArray.toJSONString(customizeEquipAttrValueVos);
                equipment.setDeviceAttributes(jsonString);
            }
            //过滤固有的设备名称 设备位置 归属园区 设备sn码
            initEquipAttrValueVos  = equipAttrValueVos.stream().filter(equipAttrValueVo -> {
                return !"02".equals(equipAttrValueVo.getType()) && !Arrays.asList("equipLocation","equipName","equipSN","ownedPark").contains(equipAttrValueVo.getName());
            }).collect(Collectors.toList());
        }
        equipment.setEquipTypeName(null);
        equipment.setEquipTypeTitle(null);
        equipment.setStatus("03");
        Device newEquipment = equipmentRepository.save(equipment);
        String equipLocation = newEquipment.getEquipLocation();
        if(!StringUtil.isEmpty(equipLocation)){
            String[] split = equipLocation.split("\\/");
            if(split.length > 1){
                //关联厂房
                equipmentRepository.bindOfficeAndDevice(newEquipment.getId(),Long.valueOf(split[1]));
            }
        }
        bindEquipTypeAndEquipTypeAttr(equipmentBo.getEquipTypeId(),newEquipment,initEquipAttrValueVos,customizeEquipAttrValueVos);
        return newEquipment;
    }


    @Override
    public Iterable<EquipmentVo> getEquipByQueryCondition(EquipmentQueryCondition equipmentQueryCondition) {
        if(CollectionUtil.isEmpty(equipmentQueryCondition.getRealStationIds())){
            String projectCode = ServerContextHolder.getContext().getProjectCode();
            if(!StringUtil.isEmpty(projectCode)){
                ResponseEntity<ResultObject<Iterable<RealStation>>> responseEntity = authorityClient.findRealStationByStationId(Long.valueOf(projectCode));
                if(responseEntity != null && responseEntity.getStatusCode().is2xxSuccessful()){
                    Object results = responseEntity.getBody().getResults();
                    List<RealStation> realStations = JSON.parseArray(JSON.toJSONString(results), RealStation.class);
                    List<Long> realStationIds = new ArrayList<>();
                    for (RealStation realStation : realStations) {
                        realStationIds.add(realStation.getId());
                    }
                    equipmentQueryCondition.setRealStationIds(realStationIds);
                }
            }
        }
        return equipmentDao.getEquipByQueryCondition(equipmentQueryCondition);
    }

    @Override
    public EquipmentBo getEquipById(Long id) throws ObjectNotFoundException {
        EquipmentBo equipmentBo = new EquipmentBo();
        Device equipment = equipmentRepository.findById(id).orElse(null);
        if(equipment == null){
            throw new ObjectNotFoundException("无此设备信息");
        }
        BeanUtils.copyProperties(equipment,equipmentBo);
        //查询设备对应的设备类型
        DeviceType equipmentType = equipmentTypeRepository.findByEuqipId(id);
        if(equipmentType != null){
            equipmentBo.setEquipTypeId(equipmentType.getId());
            equipmentBo.setEquipTypeName(equipmentType.getName());
            equipmentBo.setEquipTypePhoto(equipmentType.getPhoto());
            equipmentBo.setEquipTypeTitle(equipmentType.getTitle());
        }
        //前端需要
        EquipmentAttributes equipLocationAttr = equipmentAttributesRepository.findByName("equipLocation");
        if(equipLocationAttr != null){
            equipmentBo.setEquipLocationId(equipLocationAttr.getId());
        }
        EquipmentAttributes ownedParkAttr = equipmentAttributesRepository.findByName("ownedPark");
        if(ownedParkAttr != null){
            equipmentBo.setOwnedParkId(ownedParkAttr.getId());
        }
        EquipmentAttributes equipNameAttr = equipmentAttributesRepository.findByName("equipName");
        if(equipNameAttr != null){
            equipmentBo.setEquipTypeId(equipNameAttr.getId());
        }
        EquipmentAttributes equipSNAttr = equipmentAttributesRepository.findByName("equipSN");
        if(equipSNAttr != null){
            equipmentBo.setEquipSNId(equipSNAttr.getId());
        }
        List<EquipAttrValueVo> equipAttrValueVoList = new ArrayList<>();
        //查询设备对应设备类型的设备属性值
        List<String> names = Arrays.asList("equipLocation","ownedPark","equipName","equipSN");
        List<EquipAttrValueVo> equipAttrValueVos = equipmentDao.getEquipAttrValue(id,equipmentType.getId());
        if(!CollectionUtil.isEmpty(equipAttrValueVos)){
            //过滤设备名称设备位置归属园区设备sn码
            equipAttrValueVos.forEach(equipAttrValueVo -> {
                if(!names.contains(equipAttrValueVo.getName())){
                    equipAttrValueVoList.add(equipAttrValueVo);
                }
            });
            //equipAttrValueVoList.addAll(equipAttrValueVos);
        }
        List<EquipmentAttributes> equipmentAttributes = equipmentAttributesRepository.getEquipmentAttributesByEquipTypeId(equipmentType.getId());
        if(!CollectionUtil.isEmpty(equipmentAttributes)){
            if(CollectionUtil.isEmpty(equipAttrValueVos)){
                equipmentAttributes.forEach(equipmentAttribute -> {
                    if(!names.contains(equipmentAttribute.getName())){
                        EquipAttrValueVo equipAttrValueVo = new EquipAttrValueVo();
                        equipAttrValueVo.setId(equipmentAttribute.getId());
                        equipAttrValueVo.setComponentType(equipmentAttribute.getComponentType());
                        equipAttrValueVo.setName(equipmentAttribute.getName());
                        equipAttrValueVo.setTitle(equipmentAttribute.getTitle());
                        equipAttrValueVo.setType(equipmentAttribute.getType());
                        equipAttrValueVo.setUrl(equipmentAttribute.getUrl());
                        equipAttrValueVoList.add(equipAttrValueVo);
                    }
                });
            }else {
                    List<EquipmentAttributes> equipmentAttributesList = equipmentAttributes.stream().filter(equipmentAttribute -> {
                        List<String> collect = equipAttrValueVos.stream().map(equipAttrValueVo -> {
                            return equipAttrValueVo.getName();
                        }).collect(Collectors.toList());
                        return !collect.contains(equipmentAttribute.getName()) && !names.contains(equipmentAttribute.getName());
                    }).collect(Collectors.toList());
                    for (EquipmentAttributes equipmentAttributes1 : equipmentAttributesList) {
                        EquipAttrValueVo equipAttrValueVo = new EquipAttrValueVo();
                        equipAttrValueVo.setId(equipmentAttributes1.getId());
                        equipAttrValueVo.setComponentType(equipmentAttributes1.getComponentType());
                        equipAttrValueVo.setName(equipmentAttributes1.getName());
                        equipAttrValueVo.setTitle(equipmentAttributes1.getTitle());
                        equipAttrValueVo.setType(equipmentAttributes1.getType());
                        equipAttrValueVo.setUrl(equipmentAttributes1.getUrl());
                        equipAttrValueVoList.add(equipAttrValueVo);
                    }

            }
        }
        //自定义属性转换为指定格式
//        String deviceAttributes = equipment.getDeviceAttributes();
//        if(!StringUtil.isEmpty(deviceAttributes)){
//            List<EquipAttrValueVo> equipAttrValueVos1 = JSON.parseArray(deviceAttributes, EquipAttrValueVo.class);
//            if(!CollectionUtil.isEmpty(equipAttrValueVos1)){
//                equipAttrValueVoList.addAll(equipAttrValueVos1);
//            }
//        }
        List<EquipAttrValueVo> customEquipAttrValueVos = equipmentDao.getCustomEquipAttrValue(id);
        if(!CollectionUtil.isEmpty(customEquipAttrValueVos)){
            equipAttrValueVoList.addAll(customEquipAttrValueVos);
        }
        equipmentBo.setEquipAttrValueVos(equipAttrValueVoList);
        return equipmentBo;
    }

    @Override
    public DeviceAnlogTypeVo getEquipAndAnlogTypeById(EquipAnlogTypeQueryCondition equipAnlogTypeQueryCondition) throws ObjectNotFoundException {
        DeviceAnlogTypeVo deviceAnlogTypeVo = new DeviceAnlogTypeVo();
        List<EquipAnlogTypeVo> equipAnlogTypeVos = new ArrayList<>();
        Device equipment = equipmentRepository.findById(equipAnlogTypeQueryCondition.getEquipId()).orElse(null);
        if(equipment == null){
            throw new ObjectNotFoundException("无此设备信息");
        }
        String projectNo = resourceTreeRepository.findProjectByRealStationId(equipment.getOwnedPark());
        if(!StringUtil.isEmpty(projectNo)){
            deviceAnlogTypeVo.setCode(projectNo.substring(2,projectNo.length()));
        }
//        ResponseEntity<ResultObject<RealStation>> responseEntity = authorityClient.findByRealStationId(equipment.getOwnedPark());
//        if(responseEntity != null &&responseEntity.getStatusCode().is2xxSuccessful()){
//            RealStation realStation = (RealStation) responseEntity.getBody().getResults();
//            if(realStation != null){
//                deviceAnlogTypeVo.setCode(realStation.getName().substring(2,realStation.getName().length()));
//            }
//        }
        //查询设备对应的设备类型
        DeviceType equipmentType = equipmentTypeRepository.findByEuqipId(equipment.getId());
        equipAnlogTypeQueryCondition.setEquipTypeId(equipmentType.getId());
        List<PointDataType> anlogTypes = analogTypeRepository.getAnlogTypesByEquipTypeId(equipmentType.getId());
        List<EquipAnlogTypeVo> equipAnlogTypeVoList = equipmentDao.getEquipAndAnlogTypeById(equipAnlogTypeQueryCondition);
        if(!CollectionUtil.isEmpty(equipAnlogTypeVoList)){
            equipAnlogTypeVos.addAll(equipAnlogTypeVoList);
            if(!CollectionUtil.isEmpty(anlogTypes)){
                List<PointDataType> pointDataTypes = anlogTypes.stream().filter(anlogType -> {
                    List<String> collect = equipAnlogTypeVoList.stream().map(equipAnlogTypeVo -> {
                        return equipAnlogTypeVo.getName();
                    }).collect(Collectors.toList());
                    return !collect.contains(anlogType.getName());
                }).collect(Collectors.toList());
                for (PointDataType anlogType : pointDataTypes) {
                    EquipAnlogTypeVo equipAnlogTypeVo = new EquipAnlogTypeVo();
                    equipAnlogTypeVo.setBackType(anlogType.getBackType());
                    equipAnlogTypeVo.setId(anlogType.getId());
                    equipAnlogTypeVo.setName(anlogType.getName());
                    equipAnlogTypeVo.setTitle(anlogType.getTitle());
                    equipAnlogTypeVo.setType(anlogType.getType());
                    equipAnlogTypeVos.add(equipAnlogTypeVo);
                }
            }
        }else {
            if(!CollectionUtil.isEmpty(anlogTypes)){
                for (PointDataType anlogType : anlogTypes) {
                    EquipAnlogTypeVo equipAnlogTypeVo = new EquipAnlogTypeVo();
                    equipAnlogTypeVo.setBackType(anlogType.getBackType());
                    equipAnlogTypeVo.setId(anlogType.getId());
                    equipAnlogTypeVo.setName(anlogType.getName());
                    equipAnlogTypeVo.setTitle(anlogType.getTitle());
                    equipAnlogTypeVo.setType(anlogType.getType());
                    equipAnlogTypeVos.add(equipAnlogTypeVo);
                }
            }
        }
        deviceAnlogTypeVo.setEquipAnlogTypeVos(equipAnlogTypeVos);
//        String devicePointNumber = equipment.getDevicePointNumber();
//        if(StringUtil.isEmpty(devicePointNumber)){
//            List<EquipAnlogTypeVo> equipAnlogTypeVos1 = JSON.parseArray(devicePointNumber, EquipAnlogTypeVo.class);
//            if(!CollectionUtil.isEmpty(equipAnlogTypeVos1)){
//                equipAnlogTypeVos.addAll(equipAnlogTypeVos1);
//            }
//        }
        return deviceAnlogTypeVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void updateEquipById(EquipmentBo equipmentBo) throws UniqueConstraintsException, PinyinException {
        Device equipment = new Device();
        processBeforeSave(equipmentBo);
        BeanUtils.copyProperties(equipmentBo,equipment);
        Device device = equipmentRepository.findById(equipment.getId()).orElse(null);
        if(device != null){
            equipment.setStatus(device.getStatus());
        }
        String format = DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date());
        equipment.setUpdateTime(format);
        List<EquipAttrValueVo> equipAttrValueVos = equipmentBo.getEquipAttrValueVos();
        List<EquipAttrValueVo> initEquipAttrValueVos = new ArrayList<>();
        List<EquipAttrValueVo> customizeEquipAttrValueVos = new ArrayList<>();
        if(!CollectionUtil.isEmpty(equipAttrValueVos)){
            //过滤出用户自定义属性
            customizeEquipAttrValueVos  = equipAttrValueVos.stream().filter(equipAttrValueVo -> {
                return "02".equals(equipAttrValueVo.getType());
            }).collect(Collectors.toList());
            if(!CollectionUtil.isEmpty(customizeEquipAttrValueVos)){
                String jsonString = JSONArray.toJSONString(customizeEquipAttrValueVos);
                equipment.setDevicePointNumber(jsonString);
            }
            //过滤固有的设备名称 设备位置 归属园区 设备sn码
            initEquipAttrValueVos  = equipAttrValueVos.stream().filter(equipAttrValueVo -> {
                return !"02".equals(equipAttrValueVo.getType()) && !Arrays.asList("equipLocation","equipName","equipSN","ownedPark").contains(equipAttrValueVo.getName());
            }).collect(Collectors.toList());
        }
        equipment.setEquipTypeName(null);
        equipment.setEquipTypeTitle(null);
        Device newEquipment = equipmentRepository.save(equipment);
        String equipLocation = newEquipment.getEquipLocation();
        if(!StringUtil.isEmpty(equipLocation)){
            equipmentRepository.unbindOffice(newEquipment.getId());
            String[] split = equipLocation.split("\\/");
            if(split.length > 1){
                //关联厂房
                equipmentRepository.bindOfficeAndDevice(newEquipment.getId(),Long.valueOf(split[1]));
            }
        }
        //先解绑
        equipmentRepository.unbindEquipAttr(equipment.getId());
        equipmentRepository.unbindCustomEquipAttr(equipment.getId());
        bindEquipTypeAndEquipTypeAttr(equipmentBo.getEquipTypeId(),newEquipment,initEquipAttrValueVos, customizeEquipAttrValueVos);
    }

    private void bindEquipAnlogType(Long equipTypeId, Device newEquipment, List<EquipAnlogTypeVo> initEquipAnlogTypeVos, List<EquipAnlogTypeVo> customizeEquipAttrValueVos) throws PinyinException, ArgumentErrorException {
        if(!CollectionUtil.isEmpty(initEquipAnlogTypeVos)){
            for (EquipAnlogTypeVo initEquipAnlogTypeVo : initEquipAnlogTypeVos) {
                equipmentRepository.bindEquipAnlogType(equipTypeId,newEquipment.getId(),initEquipAnlogTypeVo.getValue(),initEquipAnlogTypeVo.getId());
            }
        }
        String projectCode = ServerContextHolder.getContext().getProjectCode();
        if(!CollectionUtil.isEmpty(customizeEquipAttrValueVos)){
            for (EquipAnlogTypeVo customizeEquipAttrValueVo : customizeEquipAttrValueVos) {
                if(customizeEquipAttrValueVo.getId() != null){
                    equipmentRepository.bindEquipAnlogType(equipTypeId,newEquipment.getId(),customizeEquipAttrValueVo.getValue(),customizeEquipAttrValueVo.getId());
                }else {
                    PointDataType pointDataType = new PointDataType();
                    pointDataType.setCreateTime(DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date()));
                    pointDataType.setName(PinyinHelper.getShortPinyin(customizeEquipAttrValueVo.getTitle()));
                    pointDataType.setSn(DateTimeUtils.getTimestamp(pointDataType.getCreateTime(),null));
                    pointDataType.setTitle(customizeEquipAttrValueVo.getTitle());
                    pointDataType.setBackType("02");
                    PointDataType byName = analogTypeRepository.findByName(pointDataType.getName());
                    if(byName != null){
                        throw new ArgumentErrorException("点号类型名称已经存在！");
                    }
                    PointDataType byTitle = analogTypeRepository.findByTitle(pointDataType.getTitle());
                    if(byTitle != null){
                        throw new ArgumentErrorException("点号类型名称已经存在！");
                    }
                    PointDataType save = analogTypeRepository.save(pointDataType);
                    equipmentTypeRepository.bindCustomizeAnlogType(equipTypeId,save.getId(),Long.valueOf(projectCode));
                    equipmentRepository.bindEquipAnlogType(equipTypeId,newEquipment.getId(),customizeEquipAttrValueVo.getValue(),save.getId());
                }
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void updateEquipAndAnlogTypById(EquipmentBo equipmentBo) throws ObjectNotFoundException, ArgumentErrorException, PinyinException {
        Device equipment = equipmentRepository.findById(equipmentBo.getId()).orElse(null);
        if(equipment == null){
            throw new ObjectNotFoundException("无此设备信息");
        }
        //校验点号值是否符合规则
        checkAnlogRule(equipmentBo);
        String format = DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date());
        equipment.setUpdateTime(format);
        List<EquipAnlogTypeVo> equipAnlogTypeVos = equipmentBo.getEquipAnlogTypeVos();
        List<EquipAnlogTypeVo> initEquipAnlogTypeVos = new ArrayList<>();
        List<EquipAnlogTypeVo> customizeEquipAttrValueVos = new ArrayList<>();
        if(!CollectionUtil.isEmpty(equipAnlogTypeVos)){
            //过滤出用户自定义属性
            customizeEquipAttrValueVos = equipAnlogTypeVos.stream().filter(equipAttrValueVo -> {
                return "02".equals(equipAttrValueVo.getBackType());
            }).collect(Collectors.toList());
            if(!CollectionUtil.isEmpty(customizeEquipAttrValueVos)){
                String jsonString = JSONArray.toJSONString(customizeEquipAttrValueVos);
                equipment.setDevicePointNumber(jsonString);
            }
            initEquipAnlogTypeVos  = equipAnlogTypeVos.stream().filter(equipAttrValueVo -> {
                return !"02".equals(equipAttrValueVo.getBackType());
            }).collect(Collectors.toList());
            //Device newEquipment = equipmentRepository.save(equipment);
            //先解绑
            equipmentRepository.unbindAnlogType(equipment.getId());
            //查询设备对应的设备类型
            DeviceType equipmentType = equipmentTypeRepository.findByEuqipId(equipmentBo.getId());
            bindEquipAnlogType(equipmentType.getId(),equipment,initEquipAnlogTypeVos,customizeEquipAttrValueVos);
        }
    }

    /**
     * 校验点号是否符合规则
     * @param equipmentBo
     * @throws ObjectNotFoundException
     * @throws ArgumentErrorException
     */
    private void checkAnlogRule(EquipmentBo equipmentBo) throws ObjectNotFoundException, ArgumentErrorException {
        Long realStationId = null;
        EquipmentBo equipById = getEquipById(equipmentBo.getId());
        if(equipById != null){
            realStationId = Long.valueOf(equipById.getOwnedPark());
        }
        String ownedParkCode = null;
//        if(realStationId != null){
//            ResponseEntity<ResultObject<RealStation>> responseEntity = authorityClient.findByRealStationId(realStationId);
//            if(responseEntity != null &&responseEntity.getStatusCode().is2xxSuccessful()){
//                RealStation realStation = (RealStation) responseEntity.getBody().getResults();
//                if(realStation != null){
//                    ownedParkCode = realStation.getName();
//                }
//            }
//        }
        String projectNo = resourceTreeRepository.findProjectByRealStationId(realStationId);
        if(!StringUtil.isEmpty(projectNo)){
            ownedParkCode = projectNo;
        }
        List<EquipAnlogTypeVo> equipAnlogTypeVos = equipmentBo.getEquipAnlogTypeVos();
        if(!CollectionUtil.isEmpty(equipAnlogTypeVos)){
            //校验点号是否符合规则
            if(!StringUtil.isEmpty(ownedParkCode)){
                for (EquipAnlogTypeVo equipAnlogTypeVo : equipAnlogTypeVos) {
                    if(!StringUtil.isNumber(equipAnlogTypeVo.getValue())){
                        throw new ArgumentErrorException(equipAnlogTypeVo.getTitle()+"点号值不能包含字符!");
                    }
                    if (!ownedParkCode.substring(2,ownedParkCode.length()).equals(equipAnlogTypeVo.getValue().substring(0,4))) {
                        throw new ArgumentErrorException(equipAnlogTypeVo.getTitle()+"点号不符合规则!");
                    }
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void deleteEquipById(Long id) {
        DeviceType byEuqipId = equipmentTypeRepository.findByEuqipId(id);
        equipmentRepository.unbindAnlogType(id);
        equipmentRepository.unbindEquipAttr(id);
        equipmentRepository.unbindEquipType(id);
        equipmentRepository.unbindOffice(id);
        equipmentRepository.unbindCustomEquipAttr(id);
        equipmentRepository.deleteById(id);
        subtractEquipCount(byEuqipId.getId());
    }

    @Override
    public EquipStatusCountVo getEquipCountByOwnedPark(List<Long> realStationIds) {
        EquipStatusCountVo equipStatusCountVo = new EquipStatusCountVo();
        List<Long> realStations = new ArrayList<>();
        if(CollectionUtil.isEmpty(realStationIds)){
            String projectCode = ServerContextHolder.getContext().getProjectCode();
            if(!StringUtil.isEmpty(projectCode)){
                ResponseEntity<ResultObject<Iterable<RealStation>>> responseEntity = authorityClient.findRealStationByStationId(Long.valueOf(projectCode));
                if (responseEntity.getStatusCode().is2xxSuccessful()) {
                    Object results = responseEntity.getBody().getResults();
                    List<RealStation> realStation = JSON.parseArray(JSON.toJSONString(results), RealStation.class);
                    for (RealStation realStation1 : realStation) {
                        realStations.add(realStation1.getId());
                    }
                }
            }
        }else {
            realStations.addAll(realStationIds);
        }
        List<Device> equipments =equipmentDao.getEquipByOwnePark(realStations);
        if(!CollectionUtil.isEmpty(equipments)){
            Map<String, Long> map = equipments.stream().collect(Collectors.groupingBy(Device::getStatus, Collectors.counting()));
            if(!CollectionUtil.isEmpty(map)){
                for (String key : map.keySet()) {
                    if("01".equals(key)){
                        equipStatusCountVo.setOnlineNum(Math.toIntExact(map.get(key)));
                    }else if("02".equals(key)){
                        equipStatusCountVo.setOfflineNum(Math.toIntExact(map.get(key)));
                    }else if("03".equals(key)){
                        equipStatusCountVo.setUnDetectedNum(Math.toIntExact(map.get(key)));
                    }
                }
            }
        }
        equipStatusCountVo.setTotalNum(equipStatusCountVo.getOfflineNum()+equipStatusCountVo.getOnlineNum()+equipStatusCountVo.getUnDetectedNum());
        return equipStatusCountVo;
    }

    @Override
    public List<EquipTypeCountVo> getEquipTypeCountByOwnedPark(List<Long> realStationIds) {
        List<EquipTypeCountVo> equipTypeCountVos = new ArrayList<>();
        List<Long> realStations = new ArrayList<>();
        if(CollectionUtil.isEmpty(realStationIds)){
            String projectCode = ServerContextHolder.getContext().getProjectCode();
            if(!StringUtil.isEmpty(projectCode)){
                ResponseEntity<ResultObject<Iterable<RealStation>>> responseEntity = authorityClient.findRealStationByStationId(Long.valueOf(projectCode));
                if (responseEntity.getStatusCode().is2xxSuccessful()) {
                    Object results = responseEntity.getBody().getResults();
                    List<RealStation> realStation = JSON.parseArray(JSON.toJSONString(results), RealStation.class);
                    for (RealStation realStation1 : realStation) {
                        realStations.add(realStation1.getId());
                    }
                }
            }
        }else {
            realStations.addAll(realStationIds);
        }
        List<Device> equipments= equipmentDao.getEquipByOwnePark(realStations);
        if(!CollectionUtil.isEmpty(equipments)){
            Map<String, List<Device>> maps = equipments.stream().collect(Collectors.groupingBy(Device::getEquipTypeName));
            if(!CollectionUtil.isEmpty(maps)){
                for (String key : maps.keySet()) {
                    EquipTypeCountVo equipTypeCountVo = new EquipTypeCountVo();
                    equipTypeCountVo.setName(key);
                    equipTypeCountVo.setTitle(maps.get(key).get(0).getEquipTypeTitle());
                    equipTypeCountVo.setCount(maps.get(key).size());
                    equipTypeCountVos.add(equipTypeCountVo);
                }
            }
        }else {
            EquipTypeCountVo equipTypeCountVo = new EquipTypeCountVo();
            equipTypeCountVo.setName("other");
            equipTypeCountVo.setTitle("其他");
            equipTypeCountVo.setCount(0);
            equipTypeCountVos.add(equipTypeCountVo);
        }
        if(equipTypeCountVos.size()>4){
            List<EquipTypeCountVo> equipTypeCountVoList = equipTypeCountVos.stream().sorted(Comparator.comparing(EquipTypeCountVo::getCount).reversed()).limit(4).collect(Collectors.toList());
            if(!CollectionUtil.isEmpty(equipTypeCountVoList)){
                List<String> collect = equipTypeCountVoList.stream().map(EquipTypeCountVo::getName).collect(Collectors.toList());
                //去除前四个的设备类型的数量
                List<Device> collect1 = equipments.stream().filter(equipment -> {
                    return !collect.contains(equipment.getEquipTypeName());
                }).collect(Collectors.toList());
                EquipTypeCountVo equipTypeCountVo = new EquipTypeCountVo();
                equipTypeCountVo.setName("other");
                equipTypeCountVo.setTitle("其他");
                equipTypeCountVo.setCount(collect1.size());
                equipTypeCountVoList.add(equipTypeCountVo);
            }
            return equipTypeCountVoList;
        }
        //查询设备类型数量
        return equipTypeCountVos;
    }

    @Override
    public List<Device> getEquipByOfficeId(List<Long> officeIds) {
        List<Device> devices = new ArrayList<>();
        for (Long officeId : officeIds) {
            Iterable<Device> equipByOfficeId = equipmentRepository.findEquipByOfficeId(officeId);
            for (Device device : equipByOfficeId) {
                devices.add(device);
            }
        }
        return devices;
    }

    @Override
    public Page<OfficeManageDeviceVO> getEquipInfoByOfficeId(Long officeId, PageParam pageParam) {
        List<OfficeManageDeviceVO> deviceInfoList = new ArrayList<>();
        List<Device> equipByOfficeId = equipmentRepository.findEquipByOfficeId(officeId);
        for (Device device : equipByOfficeId) {
            DeviceType equipmentType = equipmentTypeRepository.findByEuqipId(device.getId());
            OfficeManageDeviceVO officeManageDeviceVO = new OfficeManageDeviceVO();

            officeManageDeviceVO.setId(device.getId());
            officeManageDeviceVO.setEquipName(device.getEquipName());
            officeManageDeviceVO.setStatus(device.getStatus());
            officeManageDeviceVO.setEquipSN(device.getEquipSN());
            officeManageDeviceVO.setEquipType(equipmentType.getTitle());

            deviceInfoList.add(officeManageDeviceVO);
        }
        Page<OfficeManageDeviceVO> page = new PageImpl<>(new ArrayList<>());
        if (!CollectionUtil.isEmpty(deviceInfoList)){
            List<OfficeManageDeviceVO> content = Lists.newArrayList(deviceInfoList);
            Pageable pageable = PageRequest.of(pageParam.getPage()-1,pageParam.getSize());
            page = new PageImpl<OfficeManageDeviceVO>(content,pageable, deviceInfoList.size());
        }
        return page;
    }

    @Override
    public void downDeviceTemplate(Long equipTypeId, HttpServletResponse response) throws IOException, ArgumentErrorException {
        String projectCode = ServerContextHolder.getContext().getProjectCode();
        //String projectCode = "885";
        if(StringUtil.isEmpty(projectCode)){
            throw new ArgumentErrorException("请选择对应的项目！");
        }
        DeviceType equipmentType = equipmentTypeRepository.findById(equipTypeId).get();
        if(equipmentType == null){
            throw new ArgumentErrorException("所选择的设备类型不存在，请重新选择！");
        }
        //设置对应excel的表头
        List<EquipmentAttributes> equipmentAttributesByEquipTypeId = equipmentAttributesRepository.getEquipmentAttributesByEquipTypeId(equipTypeId);
        List<String> heards = new ArrayList<>();
        heards.add("归属园区");
        heards.add("设备位置");
        heards.add("设备名称");
        heards.add("设备SN码");
//        equipmentAttributesByEquipTypeId.forEach(equipmentAttributes -> {
//            if(!"equipLocation".equals(equipmentAttributes.getName()) && !"ownedPark".equals(equipmentAttributes.getName())){
//                heards.add(equipmentAttributes.getTitle());
//            }});
        //查询设备类型拥有的点号类型
        List<PointDataType> pointDataTypes = analogTypeRepository.getAnlogTypesByEquipTypeId(equipTypeId);
        List<String> collect1 = pointDataTypes.stream().map(pointDataType -> {
            return pointDataType.getTitle() + "点号";
        }).collect(Collectors.toList());
        heards.addAll(collect1);
        Map<String, List<String>> data = new HashMap<>();
        ResponseEntity<ResultObject<Iterable<RealStation>>> responseEntity = authorityClient.searchStationAndOfficeByStationId(Long.valueOf(projectCode));
        if(responseEntity != null){
            if (responseEntity.getStatusCode().is2xxSuccessful()) {
                Iterable<RealStation> results = responseEntity.getBody().getResults();
                if(results != null){
                    for (RealStation realStation : results) {
                        List<String> officeNames = new ArrayList<>();
                        officeNames.add("公区");
                        List<Office> offices = realStation.getOfficeList();
                        if(CollectionUtil.isNotEmpty(offices)){
                            for (Office office : offices) {
                                officeNames.add("非公区/"+office.getOfficeTitle());
                            }
                        }
                        data.put(StringUtil.isEmpty(realStation.getAbbreviationName()) ?
                                realStation.getEnterpriseFullName() : realStation.getAbbreviationName(),CollectionUtil.isNotEmpty(officeNames)?officeNames:Arrays.asList("无厂房信息"));
                    }
                }
            }
        }
        //组装excel
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode("设备类型为"+equipmentType.getTitle()+"设备批量导入模板.xls", "utf-8"));
        String sheetName = equipmentType.getTitle();
        String titleName = equipmentType.getTitle();
        String[] heardName = new String[heards.size()];
        heards.toArray(heardName);
        String pattern  = "yyyy-MM-dd";
        OutputStream outputStream = response.getOutputStream();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        bufferedOutputStream.flush();
        //生成对应的excel 工作簿 并获取对应需要设置的下拉选列的列地址
        HSSFWorkbook workbook = new ExcelExport().doExportExcel(sheetName, titleName, heardName, new ArrayList<>(), pattern,bufferedOutputStream);
        HSSFSheet excelSheet = workbook.getSheetAt(0);
        HSSFRow row = excelSheet.getRow(1);
        char ownedpark = 64;
        char equipAddr = 64;
        int physicalNumberOfCells = row.getPhysicalNumberOfCells();
        for (int i = 0; i < physicalNumberOfCells; i++) {
            HSSFCell cell = row.getCell(i);
            if(cell.getStringCellValue().equals("归属园区")){
                ownedpark = cell.getAddress().formatAsString().split("2")[0].toCharArray()[0];
            }else if(cell.getStringCellValue().equals("设备位置")){
                equipAddr = cell.getAddress().formatAsString().split("2")[0].toCharArray()[0];
            }
        }
        if(CollectionUtil.isEmpty(data)){
            data.put("暂无园区",Arrays.asList("暂无厂房"));
        }
        PoiUtils.addValidationToSheet(workbook, excelSheet, data, ownedpark, equipAddr, 2, 10000);
        // 隐藏存储下拉列表数据的sheet；可以注释掉该行以便查看、理解存储格式
        PoiUtils.hideTempDataSheet(workbook, 1);
        workbook.write(bufferedOutputStream);
        bufferedOutputStream.close();
        workbook.close();
    }

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void importDevice(MultipartFile file) throws IOException, ArgumentErrorException, UniqueConstraintsException, PinyinException, ObjectNotFoundException {
        if (file.isEmpty()) {
            throw new IOException("导入文件" + file.getName() + "不存在");
        }
        String projectCode = ServerContextHolder.getContext().getProjectCode();
        //String projectCode = "885";
        if(StringUtil.isEmpty(projectCode)){
            throw new ArgumentErrorException("请选择对应的项目进行操作！");
        }
        InputStream in = null;
        try {
            in = file.getInputStream();
            importData(file,Long.valueOf(projectCode));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            in.close();
        }
    }

    private void importData(MultipartFile file, Long stationId) throws IOException, ArgumentErrorException, UniqueConstraintsException, PinyinException, ObjectNotFoundException, InterruptedException {
//        long startTime = System.currentTimeMillis();
//        ExecutorService executorService = Executors.newSingleThreadExecutor();
//        executorService.submit(() -> {
//            batchDataProcessing();
//        });
        List<Map<String, String>> result = new ArrayList<Map<String, String>>();
        Map<String, Map<Integer, Map<String, String>>> excelToMap = UploadUtil.readExcelToMap(file, 2, 1, 1, 2);
        if (!CollectionUtil.isEmpty(excelToMap)) {
            for (Map.Entry<String, Map<Integer, Map<String, String>>> entry : excelToMap.entrySet()) {
                //设备类型  key
                String key = entry.getKey();
                DeviceType deviceType = equipmentTypeRepository.findForImportDeviceByTitleAndStationId(key, stationId);
                if (deviceType == null) {
                    throw new ArgumentErrorException(key + "设备类型不存在");
                }
                Map<Integer, Map<String, String>> values = entry.getValue();
                if(!CollectionUtil.isEmpty(values)){
                    for (Map.Entry<Integer, Map<String, String>> valueEntry : values.entrySet()) {
                        result.add(valueEntry.getValue());
                    }
                }
                parseData(result,stationId,deviceType);
            }
        }
//        deviceQueue.add(new EquipmentBo());
//        long endTime = System.currentTimeMillis();
//        log.info("数据处理所需时间：{}",(endTime-startTime));
//        log.info("数据处理结束");
//        executorService.shutdown();
//        executorService.awaitTermination(20, TimeUnit.SECONDS);
    }

    private void batchDataProcessing() {
        try {
            for (; ; ) {
                List<EquipmentBo> dataLists = new ArrayList<>(100);
                for (int i = 0; i < 50; i++) {
                    EquipmentBo take = deviceQueue.take();
                    if (take == null || take.getOwnedPark() ==null) {
                        if (!CollectionUtil.isEmpty(dataLists)) {
                            batchEquip(dataLists);
                        }
                        return;
                    } else {
                        dataLists.add(take);
                    }
                }
                if (!CollectionUtil.isEmpty(dataLists)) {
                    batchEquip(dataLists);
                    dataLists.clear();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //解析excel每列数据
    private void parseData(List<Map<String, String>> maps, Long stationId, DeviceType deviceType) throws UniqueConstraintsException, ArgumentErrorException, PinyinException, ObjectNotFoundException {
        //List<EquipmentAttributes> equipmentAttributes = equipmentAttributesRepository.getEquipmentAttributesByEquipTypeId(deviceType.getId());
        List<PointDataType> pointDataTypes = analogTypeRepository.getAnlogTypesByEquipTypeId(deviceType.getId());
        List<EquipmentBo> equipmentBos = new ArrayList<>();
        maps.forEach(map -> {
            EquipmentBo device = new EquipmentBo();
            device.setEquipTypeId(deviceType.getId());
            device.setEquipTypeName(deviceType.getName());
            if (!CollectionUtil.isEmpty(map)) {
                List<EquipAttrValueVo> equipAttrValueVos = new ArrayList<>();
                List<EquipAnlogTypeVo> equipAnlogTypeVos = new ArrayList<>();
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    String key = entry.getKey();
                    String[] strArr = key.split("-");
                    String value = entry.getValue();
                    if (strArr[0].endsWith("点号name")) {
                        //保存设备对应点号类型的点号数据
                        pointDataTypes.forEach(pointDataType -> {
                            String str = strArr[0].substring(0, strArr[0].lastIndexOf("点号name"));
                            if (pointDataType.getTitle().equals(str)) {
                                EquipAnlogTypeVo equipAnlogTypeVo = new EquipAnlogTypeVo();
                                BeanUtils.copyProperties(pointDataType, equipAnlogTypeVo);
                                equipAnlogTypeVo.setValue(value);
                                equipAnlogTypeVos.add(equipAnlogTypeVo);
                            }
                        });
                    } else {
                        if (key.contains("归属园区")) {
                            Long realStationId= authorityDao.findRealStationByStationIdAndTitle(stationId, value);
                            if(realStationId != null){
                                //跳出此次循环
                                device.setOwnedPark(realStationId);
                            }
                            //dealWithEquipAttr(stationId, equipmentAttributes, device, equipAttrValueVos, key, value);
                        } else if (key.contains("设备位置")) {
                            if (value.equals("公开")) {
                                device.setEquipLocation("01");
                            } else {
                                //查询非公开的房源id
                                String[] split = value.split("\\/");
                                Long officeId = authorityDao.findOfficeByStationIdAndTitle(device.getOwnedPark(), split[1], stationId);
                                if (officeId != null) {
                                    device.setEquipLocation("02/" + officeId);
                                }

                            }
                        } else if (key.contains("设备SN码")) {
                            device.setEquipSN(value);
                        } else if (key.contains("设备名称")) {
                            device.setEquipName(value);
                        }
                    }
                }
                device.setEquipAttrValueVos(equipAttrValueVos);
                device.setEquipAnlogTypeVos(equipAnlogTypeVos);
                equipmentBos.add(device);
                //deviceQueue.add(device);
            }
        });

        long currentTimeMillis = System.currentTimeMillis();
        batchEquip(equipmentBos);
        log.info("数据入库所需时间{}",System.currentTimeMillis()-currentTimeMillis);
    }

    /**
     * 处理设备属性
     * @param stationId
     * @param equipmentAttributes
     * @param device
     * @param equipAttrValueVos
     * @param key
     * @param value
     */
    private void dealWithEquipAttr(Long stationId, List<EquipmentAttributes> equipmentAttributes, EquipmentBo device, List<EquipAttrValueVo> equipAttrValueVos, String key, String value) {
        equipmentAttributes.forEach(equipmentAttribute -> {
            //"equipLocation","equipName","equipSN","ownedPark"
            if(key.contains(equipmentAttribute.getTitle())){
                if("ownedPark".equals(equipmentAttribute.getName())){
                    Long realStationId = authorityDao.findRealStationByStationIdAndTitle(stationId, value);
                    if(realStationId != null){
                        device.setOwnedPark(realStationId);
                    }

                }else if("equipLocation".equals(equipmentAttribute.getName())){
                    if(value.equals("公开")){
                        device.setEquipLocation("01");
                    }else {
                        //查询非公开的房源id
                        String[] split = value.split("\\/");
                        Long officeId = authorityDao.findOfficeByStationIdAndTitle(device.getOwnedPark(), split[1],stationId);
                        if(officeId != null){
                            device.setEquipLocation("02/"+officeId);
                        }

                    }
                }else if("equipSN".equals(equipmentAttribute.getName())){
                    device.setEquipSN(value);
                }else if("equipName".equals(equipmentAttribute.getName())){
                    device.setEquipName(value);
                }else {
                    EquipAttrValueVo equipAttrValueVo = new EquipAttrValueVo();
                    BeanUtils.copyProperties(equipmentAttribute,equipAttrValueVo);
                    equipAttrValueVo.setValue(value);
                    equipAttrValueVos.add(equipAttrValueVo);
                }
            }
        });
    }

    private void batchEquip(List<EquipmentBo> equipmentBos) throws ArgumentErrorException, UniqueConstraintsException, PinyinException, ObjectNotFoundException {
        //long currentTimeMillis = System.currentTimeMillis();
        if(CollectionUtil.isNotEmpty(equipmentBos)){
            Set<String> collect = equipmentBos.stream().map(EquipmentBo::getEquipName).collect(Collectors.toSet());
            if(equipmentBos.size() > collect.size()){
                throw new ArgumentErrorException("导入的设备名称存在重复，请核对数据！");
            }
//            for (EquipmentBo equipmentBo : equipmentBos) {
//                importCreateDevice(equipmentBo);
//            }
            importCreateDevice(equipmentBos);
        }
        //log.info("数据入库所需时间{}",System.currentTimeMillis()-currentTimeMillis);
    }

    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void importCreateDevice(List<EquipmentBo> equipmentBos) throws UniqueConstraintsException, PinyinException, ArgumentErrorException, ObjectNotFoundException {
        List<Device> devices = new ArrayList<>();
        for (EquipmentBo equipmentBo : equipmentBos) {
            Device equipment = new Device();
            equipmentBo.setId(null);
            processBeforeSave(equipmentBo);
            BeanUtils.copyProperties(equipmentBo,equipment);
            String format = DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(), new Date());
            equipment.setSn(DateTimeUtils.getTimestamp(format,null));
            equipment.setCreateTime(format);
            equipment.setEquipTypeName(null);
            equipment.setEquipTypeTitle(null);
            equipment.setStatus("03");
            //equipment.setEquipAnlogTypeVos(equipmentBo.getEquipAnlogTypeVos());
            devices.add(equipment);
        }

        Iterable<Device> deviceIterable = equipmentRepository.saveAll(devices);
        long currentTimeMillis = System.currentTimeMillis();
        if(deviceIterable != null){
            for (Device device : deviceIterable) {
                for (EquipmentBo equipmentBo : equipmentBos) {
                    if(equipmentBo.getEquipName().equals(device.getEquipName())){
                        equipmentBo.setId(device.getId());
                    }
                }
                String equipLocation = device.getEquipLocation();
                if(!StringUtil.isEmpty(equipLocation)){
                    String[] split = equipLocation.split("\\/");
                    if(split.length > 1){
                        //关联厂房
                        equipmentRepository.bindOfficeAndDevice(device.getId(),Long.valueOf(split[1]));
                    }
                }
            }
        }
        for (EquipmentBo equipmentBo : equipmentBos) {
            equipmentRepository.bindEquipType(equipmentBo.getEquipTypeId(),equipmentBo.getId());
            addEquipCount(equipmentBo.getEquipTypeId());
            bindEquipTypeAnlogType(equipmentBo);
        }
        log.info("关系入库所需时间:{}",System.currentTimeMillis()-currentTimeMillis);
        //Device newEquipment = equipmentRepository.save(equipment);
//        String equipLocation = newEquipment.getEquipLocation();
//        if(!StringUtil.isEmpty(equipLocation)){
//            String[] split = equipLocation.split("\\/");
//            if(split.length > 1){
//                //关联厂房
//                equipmentRepository.bindOfficeAndDevice(newEquipment.getId(),Long.valueOf(split[1]));
//            }
//        }
//        bindEquipTypeAndEquipTypeAttr(equipmentBo.getEquipTypeId(),newEquipment,null,null);
        //bindEquipTypeAnlogType(equipment);

    }

    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void bindEquipTypeAnlogType(EquipmentBo equipment) throws ArgumentErrorException, ObjectNotFoundException, PinyinException {
        //校验点号值是否符合规则
        checkAnlogRuleForImport(equipment);
        List<EquipAnlogTypeVo> equipAnlogTypeVos = equipment.getEquipAnlogTypeVos();
        if(!CollectionUtil.isEmpty(equipAnlogTypeVos)){
            for (EquipAnlogTypeVo initEquipAnlogTypeVo : equipAnlogTypeVos) {
                equipmentRepository.bindEquipAnlogType(equipment.getEquipTypeId(),equipment.getId(),initEquipAnlogTypeVo.getValue(),initEquipAnlogTypeVo.getId());
            }
        }
    }

    private void checkAnlogRuleForImport(EquipmentBo equipment) throws ObjectNotFoundException, ArgumentErrorException {
        Long realStationId = null;

        if(equipment != null){
            realStationId = Long.valueOf(equipment.getOwnedPark());
        }
        String ownedParkCode = null;
        String projectNo = resourceTreeRepository.findProjectByRealStationId(realStationId);
        if(!StringUtil.isEmpty(projectNo)){
            ownedParkCode = projectNo;
        }
        List<EquipAnlogTypeVo> equipAnlogTypeVos = equipment.getEquipAnlogTypeVos();
        if(!CollectionUtil.isEmpty(equipAnlogTypeVos)){
            //校验点号是否符合规则
            if(!StringUtil.isEmpty(ownedParkCode)){
                for (EquipAnlogTypeVo equipAnlogTypeVo : equipAnlogTypeVos) {
                    if(!StringUtil.isNumber(equipAnlogTypeVo.getValue())){
                        throw new ArgumentErrorException(equipAnlogTypeVo.getTitle()+"点号值不能包含字符!");
                    }
                    if (!ownedParkCode.substring(2,ownedParkCode.length()).equals(equipAnlogTypeVo.getValue().substring(0,4))) {
                        throw new ArgumentErrorException(equipAnlogTypeVo.getTitle()+"点号不符合规则!");
                    }
                }
            }
        }
    }


    /**
     * 绑定设备类型以及设备属性
     * @param equipTypeId
     * @param newEquipment
     * @param initEquipAttrValueVos
     * @param customizeEquipAttrValueVos
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void bindEquipTypeAndEquipTypeAttr(Long equipTypeId, Device newEquipment, List<EquipAttrValueVo> initEquipAttrValueVos, List<EquipAttrValueVo> customizeEquipAttrValueVos) throws PinyinException, UniqueConstraintsException {
        equipmentRepository.bindEquipType(equipTypeId,newEquipment.getId());
        addEquipCount(equipTypeId);
        if(!CollectionUtil.isEmpty(initEquipAttrValueVos)){
            for (EquipAttrValueVo initEquipAttrValueVo : initEquipAttrValueVos) {
                equipmentRepository.bindEquipTypeAttr(equipTypeId,newEquipment.getId(),initEquipAttrValueVo.getValue(),initEquipAttrValueVo.getId());
            }
        }
        if(!CollectionUtil.isEmpty(customizeEquipAttrValueVos)){
            for (EquipAttrValueVo vo : customizeEquipAttrValueVos) {
                EquipmentAttributes equipmentAttributes = new EquipmentAttributes();
                equipmentAttributes.setCreateTime(DateTimeUtils.format(DateTimeUtils.PATTERN.DATETIME.value(),new Date()));
                equipmentAttributes.setSn(DateTimeUtils.getTimestamp(equipmentAttributes.getCreateTime(),null));
                equipmentAttributes.setType("02");
                equipmentAttributes.setName(PinyinHelper.getShortPinyin(vo.getTitle()));
                equipmentAttributes.setComponentType("Input");
                equipmentAttributes.setTitle(vo.getTitle());
                //判断编码是否重复
                EquipmentAttributes byName = equipmentAttributesRepository.findByName(equipmentAttributes.getName());
                if(byName != null){
                    if (equipmentAttributes.getId() == null || equipmentAttributes.getId().longValue() != byName.getId().longValue()) {
                        throw new UniqueConstraintsException("该设备属性名称已存在！");
                    }
                }
                EquipmentAttributes byTitle = equipmentAttributesRepository.findByTitle(equipmentAttributes.getTitle());
                if(byTitle != null){
                    if (equipmentAttributes.getId() == null || equipmentAttributes.getId().longValue() != byName.getId().longValue()) {
                        throw new UniqueConstraintsException("该设备属性名称已存在！");
                    }
                }
                EquipmentAttributes save = equipmentAttributesRepository.save(equipmentAttributes);
                equipmentRepository.bindCustomizeEquipAttr(newEquipment.getId(),vo.getValue(),save.getId());
            }
        }
    }

    private synchronized void addEquipCount(Long equipTypeId) {
        DeviceType equipmentType = equipmentTypeRepository.findById(equipTypeId).orElse(null);
        Long equipCount = equipmentType.getEquipCount();
        equipCount = equipCount+1;
        equipmentTypeRepository.addEquipCount(equipTypeId,equipCount);
    }

    private synchronized void subtractEquipCount(Long equipTypeId){
        DeviceType equipmentType = equipmentTypeRepository.findById(equipTypeId).orElse(null);
        Long equipCount = equipmentType.getEquipCount();
        if (equipCount != 0){
            equipCount = equipCount - 1;
        }
        equipmentTypeRepository.addEquipCount(equipTypeId, equipCount);
    }

    private void processBeforeSave(EquipmentBo equipmentBo) throws UniqueConstraintsException {
        //校验设备名称是否重复
        Device device = equipmentRepository.findByEquipNameAndOwnedPark(equipmentBo.getEquipName(),equipmentBo.getOwnedPark());
        if(device != null){
            if (equipmentBo.getId() == null || device.getId().longValue() != equipmentBo.getId().longValue()) {
                throw new UniqueConstraintsException("该设备名称已存在");
            }
        }
    }
}
